{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "regression.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "private_outputs": true,
      "collapsed_sections": [],
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "FhGuhbZ6M5tl"
      },
      "source": [
        "##### Copyright 2018 The TensorFlow Authors."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "colab_type": "code",
        "id": "AwOEIRJC6Une",
        "colab": {}
      },
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "colab_type": "code",
        "id": "KyPEtTqk6VdG",
        "colab": {}
      },
      "source": [
        "#@title MIT License\n",
        "#\n",
        "# Copyright (c) 2017 François Chollet\n",
        "#\n",
        "# Permission is hereby granted, free of charge, to any person obtaining a\n",
        "# copy of this software and associated documentation files (the \"Software\"),\n",
        "# to deal in the Software without restriction, including without limitation\n",
        "# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n",
        "# and/or sell copies of the Software, and to permit persons to whom the\n",
        "# Software is furnished to do so, subject to the following conditions:\n",
        "#\n",
        "# The above copyright notice and this permission notice shall be included in\n",
        "# all copies or substantial portions of the Software.\n",
        "#\n",
        "# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n",
        "# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n",
        "# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n",
        "# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n",
        "# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n",
        "# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n",
        "# DEALINGS IN THE SOFTWARE."
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "EIdT9iu_Z4Rb"
      },
      "source": [
        "# Regresion Basica: Predecir eficiencia de gasolina"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "bBIlTPscrIT9"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://www.tensorflow.org/tutorials/keras/regression\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on TensorFlow.org</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/es/tutorials/keras/regression.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/es/tutorials/keras/regression.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a href=\"https://storage.googleapis.com/tensorflow_docs/docs/site/es/tutorials/keras/regression.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\" />Download notebook</a>\n",
        "  </td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Au0QDqNXgRb_",
        "colab_type": "text"
      },
      "source": [
        "Note: Nuestra comunidad de Tensorflow ha traducido estos documentos. Como las traducciones de la comunidad\n",
        "son basados en el \"mejor esfuerzo\", no hay ninguna garantia que esta sea un reflejo preciso y actual \n",
        "de la [Documentacion Oficial en Ingles](https://www.tensorflow.org/?hl=en).\n",
        "Si tienen sugerencias sobre como mejorar esta traduccion, por favor envian un \"Pull request\"\n",
        "al siguiente repositorio [tensorflow/docs](https://github.com/tensorflow/docs).\n",
        "Para ofrecerse como voluntario o hacer revision de las traducciones de la Comunidad\n",
        "por favor contacten al siguiente grupo [docs@tensorflow.org list](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "AHp3M9ZmrIxj"
      },
      "source": [
        "En un problema de *regresion*, buscamos predecir la salida de un valor continuo como la probabilidad de un precio. En contraste en un problema de *Clasificacion*, buscamos seleccionar una clase de una lista de clases (por ejemplo, en donde una imagen contenga una manzana o una naranja queremos reconocer cual es la fruta en la imagen).\n",
        "\n",
        "Este libro usa el set de datos clasico [Auto MPG](https://archive.ics.uci.edu/ml/datasets/auto+mpg) y construye un modelo para predecir la eficiencia de vehiculos de 1970 y 1980. Para hacer esto proveeremos el modelo con una descripcion de muchos automoviles de ese periodo. Esta descripcion incluye atributos como: Cilindros, desplazamiento, potencia y peso.\n",
        "\n",
        "Este ejemplo usa el API `tf.keras` , revise [Esta Guia](https://www.tensorflow.org/guide/keras) para obtener mas detalles."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "moB4tpEHxKB3",
        "colab": {}
      },
      "source": [
        "# Use seaborn for pairplot\n",
        "!pip install seaborn"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "1rRo8oNqZ-Rj",
        "colab": {}
      },
      "source": [
        "from __future__ import absolute_import, division, print_function, unicode_literals\n",
        "\n",
        "import pathlib\n",
        "\n",
        "import matplotlib.pyplot as plt\n",
        "import pandas as pd\n",
        "import seaborn as sns\n",
        "\n",
        "try:\n",
        "  # %tensorflow_version only exists in Colab.\n",
        "  %tensorflow_version 2.x\n",
        "except Exception:\n",
        "  pass\n",
        "import tensorflow as tf\n",
        "\n",
        "from tensorflow import keras\n",
        "from tensorflow.keras import layers\n",
        "\n",
        "print(tf.__version__)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "F_72b0LCNbjx"
      },
      "source": [
        "## El set de Datos de MPG\n",
        "\n",
        "el set de datos esta disponible de el siguiente repositorio [UCI Machine Learning Repository](https://archive.ics.uci.edu/ml/).\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "gFh9ne3FZ-On"
      },
      "source": [
        "### Obtenga la data\n",
        "Primero descargue el set de datos."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "p9kxxgzvzlyz",
        "colab": {}
      },
      "source": [
        "dataset_path = keras.utils.get_file(\"auto-mpg.data\", \"http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data\")\n",
        "dataset_path"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "nslsRLh7Zss4"
      },
      "source": [
        "Importelo usando pandas."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "CiX2FI4gZtTt",
        "colab": {}
      },
      "source": [
        "column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight',\n",
        "                'Acceleration', 'Model Year', 'Origin']\n",
        "raw_dataset = pd.read_csv(dataset_path, names=column_names,\n",
        "                      na_values = \"?\", comment='\\t',\n",
        "                      sep=\" \", skipinitialspace=True)\n",
        "\n",
        "dataset = raw_dataset.copy()\n",
        "dataset.tail()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "3MWuJTKEDM-f"
      },
      "source": [
        "### Limpie la data\n",
        "\n",
        "El set de datos contiene algunos valores desconocidos."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "JEJHhN65a2VV",
        "colab": {}
      },
      "source": [
        "dataset.isna().sum()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "9UPN0KBHa_WI"
      },
      "source": [
        "**Para** Mantener este tutorial inicial sencillo eliminemos las siguientes filas."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "4ZUDosChC1UN",
        "colab": {}
      },
      "source": [
        "dataset = dataset.dropna()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "8XKitwaH4v8h"
      },
      "source": [
        "La columna de `\"Origin\"` realmente es categorica, no numerica. Entonces conviertala a un \"one-hot\":"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "gWNTD2QjBWFJ",
        "colab": {}
      },
      "source": [
        "origin = dataset.pop('Origin')"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "ulXz4J7PAUzk",
        "colab": {}
      },
      "source": [
        "dataset['USA'] = (origin == 1)*1.0\n",
        "dataset['Europe'] = (origin == 2)*1.0\n",
        "dataset['Japan'] = (origin == 3)*1.0\n",
        "dataset.tail()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "Cuym4yvk76vU"
      },
      "source": [
        "### Dividamos la data en entrenamiento y prueba\n",
        "\n",
        "Ahora divida el set de datos en un set de entrenamiento y otro de pruebas.\n",
        "\n",
        "Usaremos el set de pruebas en la evaluacion final de nuestro modelo."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "qn-IGhUE7_1H",
        "colab": {}
      },
      "source": [
        "train_dataset = dataset.sample(frac=0.8,random_state=0)\n",
        "test_dataset = dataset.drop(train_dataset.index)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "J4ubs136WLNp"
      },
      "source": [
        "### Inspeccione la data\n",
        "\n",
        "Revise rapidamente la distribucion conjunta de un par de columnas de el set de entrenamiento."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "oRKO_x8gWKv-",
        "colab": {}
      },
      "source": [
        "sns.pairplot(train_dataset[[\"MPG\", \"Cylinders\", \"Displacement\", \"Weight\"]], diag_kind=\"kde\")"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "gavKO_6DWRMP"
      },
      "source": [
        "Tambien revise las estadisticas generales:"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "yi2FzC3T21jR",
        "colab": {}
      },
      "source": [
        "train_stats = train_dataset.describe()\n",
        "train_stats.pop(\"MPG\")\n",
        "train_stats = train_stats.transpose()\n",
        "train_stats"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "Db7Auq1yXUvh"
      },
      "source": [
        "### Separe las caracteristicas de las etiquetas.\n",
        "\n",
        "Separe el valor objetivo, o la \"etiqueta\" \n",
        "de las caracteristicas. Esta etiqueta es el valor que entrenara el modelo para predecir."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "t2sluJdCW7jN",
        "colab": {}
      },
      "source": [
        "train_labels = train_dataset.pop('MPG')\n",
        "test_labels = test_dataset.pop('MPG')"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "mRklxK5s388r"
      },
      "source": [
        "### Normalice la data\n",
        "\n",
        "Revise otra vez el bloque de `train_stats` que se presento antes y note la diferencia de rangos de cada caracteristica."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "-ywmerQ6dSox"
      },
      "source": [
        "Es una buena práctica normalizar funciones que utilizan diferentes escalas y rangos. Aunque el modelo * podría * converger sin normalización de características, dificulta el entrenamiento y hace que el modelo resultante dependa de la elección de las unidades utilizadas en la entrada.\n",
        "\n",
        "Nota: Aunque generamos intencionalmente estas estadísticas solo del conjunto de datos de entrenamiento, estas estadísticas también se utilizarán para normalizar el conjunto de datos de prueba. Necesitamos hacer eso para proyectar el conjunto de datos de prueba en la misma distribución en la que el modelo ha sido entrenado."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "JlC5ooJrgjQF",
        "colab": {}
      },
      "source": [
        "def norm(x):\n",
        "  return (x - train_stats['mean']) / train_stats['std']\n",
        "normed_train_data = norm(train_dataset)\n",
        "normed_test_data = norm(test_dataset)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "BuiClDk45eS4"
      },
      "source": [
        "Estos datos normalizados es lo que usaremos para entrenar el modelo.\n",
        "\n",
        "Precaución: las estadísticas utilizadas para normalizar las entradas aquí (media y desviación estándar) deben aplicarse a cualquier otro dato que se alimente al modelo, junto con la codificación de un punto que hicimos anteriormente. Eso incluye el conjunto de pruebas, así como los datos en vivo cuando el modelo se usa en producción."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "SmjdzxKzEu1-"
      },
      "source": [
        "## El modelo"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "6SWtkIjhrZwa"
      },
      "source": [
        "### Construye el modelo\n",
        "\n",
        "Construyamos nuestro modelo. Aquí, utilizaremos un modelo `secuencial` con dos capas ocultas densamente conectadas y una capa de salida que devuelve un único valor continuo. Los pasos de construcción del modelo se envuelven en una función, `build_model`, ya que crearemos un segundo modelo, más adelante."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "c26juK7ZG8j-",
        "colab": {}
      },
      "source": [
        "def build_model():\n",
        "  model = keras.Sequential([\n",
        "    layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]),\n",
        "    layers.Dense(64, activation='relu'),\n",
        "    layers.Dense(1)\n",
        "  ])\n",
        "\n",
        "  optimizer = tf.keras.optimizers.RMSprop(0.001)\n",
        "\n",
        "  model.compile(loss='mse',\n",
        "                optimizer=optimizer,\n",
        "                metrics=['mae', 'mse'])\n",
        "  return model"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "cGbPb-PHGbhs",
        "colab": {}
      },
      "source": [
        "model = build_model()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "Sj49Og4YGULr"
      },
      "source": [
        "### Inspeccione el modelo\n",
        "\n",
        "Use el método `.summary` para imprimir una descripción simple del modelo"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "ReAD0n6MsFK-",
        "colab": {}
      },
      "source": [
        "model.summary()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "Vt6W50qGsJAL"
      },
      "source": [
        "\n",
        "Ahora pruebe el modelo. Tome un lote de ejemplos `10` de los datos de entrenamiento y llame a` model.predict` en él."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "-d-gBaVtGTSC",
        "colab": {}
      },
      "source": [
        "example_batch = normed_train_data[:10]\n",
        "example_result = model.predict(example_batch)\n",
        "example_result"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "QlM8KrSOsaYo"
      },
      "source": [
        "Parece estar funcionando, y produce un resultado de la forma y tipo esperados."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "0-qWCsh6DlyH"
      },
      "source": [
        "### Entrenar a la modelo\n",
        "\n",
        "Entrene el modelo durante 1000 épocas y registre la precisión de entrenamiento y validación en el objeto `history`."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "sD7qHCmNIOY0",
        "colab": {}
      },
      "source": [
        "# Display training progress by printing a single dot for each completed epoch\n",
        "class PrintDot(keras.callbacks.Callback):\n",
        "  def on_epoch_end(self, epoch, logs):\n",
        "    if epoch % 100 == 0: print('')\n",
        "    print('.', end='')\n",
        "\n",
        "EPOCHS = 1000\n",
        "\n",
        "history = model.fit(\n",
        "  normed_train_data, train_labels,\n",
        "  epochs=EPOCHS, validation_split = 0.2, verbose=0,\n",
        "  callbacks=[PrintDot()])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "tQm3pc0FYPQB"
      },
      "source": [
        "Visualice el progreso de entrenamiento del modelo usando las estadísticas almacenadas en el objeto `history`."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "4Xj91b-dymEy",
        "colab": {}
      },
      "source": [
        "hist = pd.DataFrame(history.history)\n",
        "hist['epoch'] = history.epoch\n",
        "hist.tail()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "B6XriGbVPh2t",
        "colab": {}
      },
      "source": [
        "def plot_history(history):\n",
        "  hist = pd.DataFrame(history.history)\n",
        "  hist['epoch'] = history.epoch\n",
        "\n",
        "  plt.figure()\n",
        "  plt.xlabel('Epoch')\n",
        "  plt.ylabel('Mean Abs Error [MPG]')\n",
        "  plt.plot(hist['epoch'], hist['mae'],\n",
        "           label='Train Error')\n",
        "  plt.plot(hist['epoch'], hist['val_mae'],\n",
        "           label = 'Val Error')\n",
        "  plt.ylim([0,5])\n",
        "  plt.legend()\n",
        "\n",
        "  plt.figure()\n",
        "  plt.xlabel('Epoch')\n",
        "  plt.ylabel('Mean Square Error [$MPG^2$]')\n",
        "  plt.plot(hist['epoch'], hist['mse'],\n",
        "           label='Train Error')\n",
        "  plt.plot(hist['epoch'], hist['val_mse'],\n",
        "           label = 'Val Error')\n",
        "  plt.ylim([0,20])\n",
        "  plt.legend()\n",
        "  plt.show()\n",
        "\n",
        "\n",
        "plot_history(history)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "AqsuANc11FYv"
      },
      "source": [
        "Este gráfico muestra poca mejora, o incluso degradación en el error de validación después de aproximadamente 100 épocas. Actualicemos la llamada `model.fit` para detener automáticamente el entrenamiento cuando el puntaje de validación no mejore. Utilizaremos una * devolución de llamada de EarlyStopping * que pruebe una condición de entrenamiento para cada época. Si transcurre una cantidad determinada de épocas sin mostrar mejoría, entonces detiene automáticamente el entrenamiento.\n",
        "\n",
        "Puedes obtener más información sobre esta devolución de llamada [Aca](https://www.tensorflow.org/versions/master/api_docs/python/tf/keras/callbacks/EarlyStopping)."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "fdMZuhUgzMZ4",
        "colab": {}
      },
      "source": [
        "model = build_model()\n",
        "\n",
        "# The patience parameter is the amount of epochs to check for improvement\n",
        "early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)\n",
        "\n",
        "history = model.fit(normed_train_data, train_labels, epochs=EPOCHS,\n",
        "                    validation_split = 0.2, verbose=0, callbacks=[early_stop, PrintDot()])\n",
        "\n",
        "plot_history(history)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "3St8-DmrX8P4"
      },
      "source": [
        "El gráfico muestra que en el conjunto de validación, el error promedio generalmente es de alrededor de +/- 2 MPG. ¿Es esto bueno? Le dejaremos esa decisión a usted.\n",
        "\n",
        "Veamos qué tan bien generaliza el modelo al usar el conjunto ** test **, que no usamos al entrenar el modelo. Esto nos dice qué tan bien podemos esperar que el modelo prediga cuándo lo usamos en el mundo real."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "jl_yNr5n1kms",
        "colab": {}
      },
      "source": [
        "loss, mae, mse = model.evaluate(normed_test_data, test_labels, verbose=2)\n",
        "\n",
        "print(\"Testing set Mean Abs Error: {:5.2f} MPG\".format(mae))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "ft603OzXuEZC"
      },
      "source": [
        "### Haga Predicciones\n",
        "\n",
        "Finalmente, prediga los valores de MPG utilizando datos en el conjunto de pruebas:"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "Xe7RXH3N3CWU",
        "colab": {}
      },
      "source": [
        "test_predictions = model.predict(normed_test_data).flatten()\n",
        "\n",
        "plt.scatter(test_labels, test_predictions)\n",
        "plt.xlabel('True Values [MPG]')\n",
        "plt.ylabel('Predictions [MPG]')\n",
        "plt.axis('equal')\n",
        "plt.axis('square')\n",
        "plt.xlim([0,plt.xlim()[1]])\n",
        "plt.ylim([0,plt.ylim()[1]])\n",
        "_ = plt.plot([-100, 100], [-100, 100])\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "19wyogbOSU5t"
      },
      "source": [
        "Parece que nuestro modelo predice razonablemente bien. Echemos un vistazo a la distribución de errores."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "f-OHX4DiXd8x",
        "colab": {}
      },
      "source": [
        "error = test_predictions - test_labels\n",
        "plt.hist(error, bins = 25)\n",
        "plt.xlabel(\"Prediction Error [MPG]\")\n",
        "_ = plt.ylabel(\"Count\")"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "m0CB5tBjSU5w"
      },
      "source": [
        "No es del todo gaussiano, pero podríamos esperar eso porque el número de muestras es muy pequeño."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "vgGQuV-yqYZH"
      },
      "source": [
        "## Conclusion\n",
        "\n",
        "Este cuaderno introdujo algunas técnicas para manejar un problema de regresión.\n",
        "\n",
        "* El error cuadrático medio (MSE) es una función de pérdida común utilizada para problemas de regresión (se utilizan diferentes funciones de pérdida para problemas de clasificación).\n",
        "* Del mismo modo, las métricas de evaluación utilizadas para la regresión difieren de la clasificación. Una métrica de regresión común es el error absoluto medio (MAE).\n",
        "* Cuando las características de datos de entrada numéricos tienen valores con diferentes rangos, cada característica debe escalarse independientemente al mismo rango.\n",
        "* Si no hay muchos datos de entrenamiento, una técnica es preferir una red pequeña con pocas capas ocultas para evitar el sobreajuste.\n",
        "* La detención temprana es una técnica útil para evitar el sobreajuste."
      ]
    }
  ]
}